package com.rex.saas.controller;

import com.alibaba.fastjson.JSONObject;
import com.rex.saas.bean.*;
import com.rex.saas.bean.request.*;
import com.rex.saas.bean.response.*;
import com.rex.saas.constants.Constants;
import com.rex.saas.db.entity.SaasSpaceDeviceRelation;
import com.rex.saas.db.entity.SaasSpaceInfo;
import com.rex.saas.db.entity.SaasSpacePrice;
import com.rex.saas.db.entity.SaasSpacePriceDetails;
import com.rex.saas.enums.PriceTypeEnum;
import com.rex.saas.enums.SpaceTypeEnum;
import com.rex.saas.service.*;
import com.rex.saas.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName SpaceController
 * @Description:
 * @Author: zhusiyu
 * @CreateDate: 2024/12/18 10:55	//创建时间
 */
@RestController
@Slf4j
@RequestMapping("/space")
public class SpaceController extends BaseController{

    @Autowired
    private AssetService assetService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private SpaceService spaceService;

    @Autowired
    private StatisticsService statisticsService;

    @Autowired
    private RexolarApiClient rexolarApiClient;
    @PostMapping("/list")
    public BaseResponse list(HttpServletRequest request){
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isEmpty(tenantId)){
            log.error("list tenantId is null,spaceInfoId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        List<AssetResponse> list = assetService.list(token);
        return BaseResponse.ok(list);
    }

    @PostMapping("/list/v2")
    public BaseResponse listV2(HttpServletRequest request){
        String token = request.getHeader("token");
        List< String> roles = JwtUtils.getRole(token);
        if(!roles.contains(Constants.TENANT_ADMIN)){
            log.error("list , user has not permission");
            return BaseResponse.error("权限不足", ResultCode.PARAM_ERROR);
        }
        String tenantId = JwtUtils.getTenantId(token);
        List<SpaceInfo> list = spaceService.list(tenantId);
        return BaseResponse.ok(list);
    }

    @GetMapping("/customer/list")
    public BaseResponse customerList(HttpServletRequest request){
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isEmpty(tenantId)){
            log.error("customerList tenantId is null,spaceInfoId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        List<SaasSpaceResponse> responses = new ArrayList<>();
        List<SaasSpaceInfo> customerList = spaceService.getCustomerSpaceList(token);
        for (SaasSpaceInfo saasSpaceInfo : customerList){
            SaasSpaceResponse saasSpaceResponse = new SaasSpaceResponse();
            BeanUtils.copyProperties(saasSpaceInfo, saasSpaceResponse);
            saasSpaceResponse.setGmtCreated(saasSpaceInfo.getGmtCreated().getTime());
            responses.add(saasSpaceResponse);
        }
        return BaseResponse.ok(responses);
    }

    @GetMapping("/devices")
    public BaseResponse devices(HttpServletRequest request, @RequestParam String spaceId){
        log.info("devices spaceInfoId:{}", spaceId);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isEmpty(tenantId)){
            log.error("devices tenantId is null,spaceInfoId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        List<DeviceDetailResponse> list = assetService.devices(spaceId, token);
        return BaseResponse.ok(list);
    }

    @GetMapping("/devices/v2")
    public BaseResponse devicesV2(HttpServletRequest request, @RequestParam Long spaceId){
        log.info("devicesV2 spaceId:{}", spaceId);
        String token = request.getHeader("token");
        BaseResponse baseResponse = validateSpace(spaceId, token);
        if(!baseResponse.isSuccess()){
            log.error("devicesV2 validateSpace error, spaceId:{}", spaceId);
            return baseResponse;
        }
        DeviceListRequest deviceListRequest = new DeviceListRequest();
        deviceListRequest.setSpaceInfoId(spaceId);
        return BaseResponse.ok(deviceService.listV2(deviceListRequest,  token));
    }

    @GetMapping("/details")
    public BaseResponse details(HttpServletRequest request, @RequestParam String spaceId){
        log.info("details spaceInfoId:{}", spaceId);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isEmpty(tenantId)){
            log.error("details tenantId is null,spaceInfoId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        AssetBasicData data = rexolarApiClient.getAssetById(spaceId, token);
        if (data==null){
            log.error("details AssetBasicData is null,spaceInfoId:{}", spaceId);
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }
        AssetDetailResponse assetDetailResponse = assetService.details(spaceId, token);
        assetDetailResponse.setSpaceName(data.getLabel());
        assetDetailResponse.setSpaceId(spaceId);
        return BaseResponse.ok(assetDetailResponse);
    }
    @GetMapping("/detail")
    public BaseResponse detail(HttpServletRequest request, @RequestParam Long spaceId){
        log.info("detail spaceInfoId:{}", spaceId);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isEmpty(tenantId)){
            log.error("detail tenantId is null,spaceInfoId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        BaseResponse baseResponse = validateSpace(spaceId, token);
        if(!baseResponse.isSuccess()){
            log.error("detail validateSpace error, spaceId:{}", spaceId);
            return baseResponse;
        }

        SpaceDetailResponse assetDetailResponse = spaceService.detail(spaceId);
        return BaseResponse.ok(assetDetailResponse);
    }

    @PostMapping("/bindAssetDevices")
    public BaseResponse bindAssetDevices(HttpServletRequest request, @RequestBody BindAssetDevicesRequest bindAssetDevicesRequest){
        log.info("bindAssetDevices bindAssetDevicesRequest:{}", bindAssetDevicesRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isEmpty(tenantId)){
            log.error("bindAssetDevices tenantId is null,spaceInfoId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isEmpty(bindAssetDevicesRequest.getSpaceId())){
            log.error("bindAssetDevices spaceInfoId is null,spaceInfoId:{}", bindAssetDevicesRequest.getSpaceId());
            return BaseResponse.error("空间ID不能为空", ResultCode.PARAM_ERROR);
        }
        if(CollectionUtils.isEmpty(bindAssetDevicesRequest.getDeviceNames())){
            log.error("bindAssetDevices deviceNames is null,spaceInfoId:{}", bindAssetDevicesRequest.getDeviceNames());
            return BaseResponse.error("设备列表不能为空", ResultCode.PARAM_ERROR);
        }
        for(String deviceName : bindAssetDevicesRequest.getDeviceNames()){
            DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, token);
            if(deviceBasicData==null){
                log.error("bindAssetDevices getDeviceByDeviceName error, deviceName:{}", deviceName);
                return BaseResponse.error("设备不存在：" + deviceName , ResultCode.PARAM_ERROR);
            }
            boolean flag = assetService.addAssetDevices(tenantId, bindAssetDevicesRequest.getSpaceId(), deviceName);
            if(!flag){
                log.error("addAssetDevices error, bindAssetDevicesRequest:{}", bindAssetDevicesRequest);
                return BaseResponse.error("添加设备失败", ResultCode.SYSTEM_ERROR);
            }
        }
        return BaseResponse.ok();
    }

    @PostMapping("/unbindAssetDevices")
    public BaseResponse unbindAssetDevices(HttpServletRequest request, @RequestBody UnbindTenantDevicesRequest unbindTenantDevicesRequest){
        log.info("unbindAssetDevices unbindTenantDevicesRequest:{}", unbindTenantDevicesRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isEmpty(tenantId)){
            log.error("unbindAssetDevices tenantId is null,spaceInfoId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isEmpty(unbindTenantDevicesRequest.getSpaceId())){
            log.error("unbindAssetDevices spaceInfoId is null,spaceInfoId:{}", unbindTenantDevicesRequest.getSpaceId());
            return BaseResponse.error("空间ID不能为空", ResultCode.PARAM_ERROR);
        }
        if(CollectionUtils.isEmpty(unbindTenantDevicesRequest.getDeviceNames())){
            log.error("unbindAssetDevices deviceNames is null,spaceInfoId:{}", unbindTenantDevicesRequest.getDeviceNames());
            return BaseResponse.error("设备列表不能为空", ResultCode.PARAM_ERROR);
        }

        BaseResponse validateSpace = validateSpace(unbindTenantDevicesRequest.getSpaceId(), token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("unbindAssetDevices validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }
        SaasSpaceInfo spaceInfo = spaceService.getSpaceById(unbindTenantDevicesRequest.getSpaceId());

        for(String deviceName : unbindTenantDevicesRequest.getDeviceNames()){
            DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, token);
            if(deviceBasicData==null){
                log.error("unbindAssetDevices getDeviceByDeviceName error, deviceName:{}", deviceName);
                return BaseResponse.error("设备不存在：" + deviceName , ResultCode.PARAM_ERROR);
            }
            boolean flag = assetService.unbindAssetDevices(tenantId, spaceInfo.getCoreId(), deviceName);
            if(!flag){
                log.error("unbindAssetDevices error, unbindTenantDevicesRequest:{}", unbindTenantDevicesRequest);
                return BaseResponse.error("解绑设备失败", ResultCode.SYSTEM_ERROR);
            }
        }
        return BaseResponse.ok();
    }
    @PostMapping("/add")
    public BaseResponse add(HttpServletRequest request, @RequestBody SpaceAddRequest spaceAddRequest){
        log.info("add space ===> spaceAddRequest:{}", spaceAddRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        List< String> roles = JwtUtils.getRole(token);
        if(!roles.contains(Constants.TENANT_ADMIN)){
            log.error("add no permission,spaceAddRequest:{}", spaceAddRequest);
            return BaseResponse.error("没有权限", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isEmpty(spaceAddRequest.getSpaceName())){
            log.error("add, spaceName is null,spaceInfoId:{}", spaceAddRequest.getSpaceName());
            return BaseResponse.error("空间名称不能为空", ResultCode.PARAM_ERROR);
        }
        List<SaasSpaceInfo> spaces = spaceService.getSpaceByName(spaceAddRequest.getSpaceName(), tenantId);
        if(!CollectionUtils.isEmpty(spaces)){
            log.error("add space fail, spaceName:{}", spaceAddRequest.getSpaceName());
            return BaseResponse.error("空间名称已存在", ResultCode.PARAM_ERROR);
        }
        AssetBasicData assetBasicData = rexolarApiClient.getAssetByName(spaceAddRequest.getSpaceName(), token);
        if(assetBasicData!=null){
            log.error("add getAssetByName space fail, spaceName:{}", spaceAddRequest.getSpaceName());
            return BaseResponse.error("空间名称已存在", ResultCode.PARAM_ERROR);
        }

        Long id = spaceService.add(spaceAddRequest.getSpaceName(), token);
        if(id == null){
            log.error("add space fail, spaceAddRequest:{}", spaceAddRequest);
            return BaseResponse.error("添加失败", ResultCode.PARAM_ERROR);
        }
        Map<String, Long> result = new HashMap<>();
        result.put("id", id);
        return BaseResponse.ok(result);
    }
    @PostMapping("/addCustomerSpace")
    public BaseResponse addCustomerSpace(HttpServletRequest request, @RequestBody SpaceAddRequest spaceAddRequest){
        log.info("addCustomerSpace space ===> spaceAddRequest:{}", spaceAddRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isEmpty(tenantId)){
            log.error("add tenantId is null,spaceInfoId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isEmpty(spaceAddRequest.getSpaceName())){
            log.error("add spaceName is null,spaceInfoId:{}", spaceAddRequest.getSpaceName());
            return BaseResponse.error("空间名称不能为空", ResultCode.PARAM_ERROR);
        }

        List<String> roles = JwtUtils.getRole(token);
        if(!roles.contains(Constants.CUSTOMER_USER)){
            log.error("addCustomerSpace no permission,spaceInfoId:{}", tenantId);
            return BaseResponse.error("没有权限", ResultCode.PARAM_ERROR);
        }

        String tenantToken = rexolarApiClient.getTenantToken(tenantId);
        if(StringUtils.isEmpty(tenantToken)){
            log.error("add tenantToken is null,spaceInfoId:{}", tenantToken);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        List<SaasSpaceInfo> spaces = spaceService.getSpaceByName(spaceAddRequest.getSpaceName(), tenantId);
        if(!CollectionUtils.isEmpty(spaces)){
            log.error("add space fail, spaceName:{}", spaceAddRequest.getSpaceName());
            return BaseResponse.error("空间名称已存在", ResultCode.PARAM_ERROR);
        }
        AssetBasicData assetBasicData = rexolarApiClient.getAssetByName(spaceAddRequest.getSpaceName(), tenantToken);
        if(assetBasicData!=null){
            log.error("add getAssetByName space fail, spaceName:{}", spaceAddRequest.getSpaceName());
            return BaseResponse.error("空间名称已存在", ResultCode.PARAM_ERROR);
        }

        Long id = spaceService.addCustomerSpace(spaceAddRequest, token);
        if(id == null){
            log.error("add space fail, spaceAddRequest:{}", spaceAddRequest);
            return BaseResponse.error("添加失败", ResultCode.PARAM_ERROR);
        }
        Map<String, Long> result = new HashMap<>();
        result.put("id", id);
        return BaseResponse.ok(result);
    }

    @GetMapping("getType")
    public BaseResponse getType(HttpServletRequest request, @RequestParam Long id){
        log.info("getType ===> spaceInfoId:{}", id);
        if (id == null){
            log.error("getType spaceInfoId is null,spaceInfoId:{}", id);
            return BaseResponse.error("id不能为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String customerId = JwtUtils.getCustomerId(token);
        SaasSpaceInfo space = spaceService.getSpaceById(id);
        if(space==null){
            log.error("getType space is null,spaceInfoId:{}", id);
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }
        BaseResponse validateSpace = validateSpace(id, token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("getType validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }
        List<AssetBasicData> assetBasicDatas = rexolarApiClient.getCustomerAssets(customerId, token);
        AssetBasicData spaceBasicData = assetBasicDatas.stream().filter(assetBasicData -> assetBasicData.getName()
                .equals(space.getName())).findFirst().orElse(null);
        if(spaceBasicData==null){
            log.error("getType getCustomerAssetsByName space fail, customerId:{}, spaceName:{}", customerId, space.getName());
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }

        return BaseResponse.ok(space.getType());
    }

    @GetMapping("getBaseLoad")
    public BaseResponse getBaseLoad(HttpServletRequest request, @RequestParam Long id){
        log.info("getBaseLoad ===> spaceInfoId:{}", id);
        if (id == null){
            log.error("getBaseLoad spaceInfoId is null,spaceInfoId:{}", id);
            return BaseResponse.error("id不能为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String customerId = JwtUtils.getCustomerId(token);
        SaasSpaceInfo space = spaceService.getSpaceById(id);
        if(space==null){
            log.error("getBaseLoad space is null,spaceInfoId:{}", id);
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }
        BaseResponse validateSpace = validateSpace(id, token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("getBaseLoad validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }
        List<AssetBasicData> assetBasicDatas = rexolarApiClient.getCustomerAssets(customerId, token);
        AssetBasicData spaceBasicData = assetBasicDatas.stream().filter(assetBasicData -> assetBasicData.getName()
                .equals(space.getName())).findFirst().orElse(null);
        if(spaceBasicData==null){
            log.error("getBaseLoad getCustomerAssetsByName space fail, customerId:{}, spaceName:{}", customerId, space.getName());
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }
        JSONObject extendsInfo = JSONObject.parseObject(space.getExtendsInfo());
        return BaseResponse.ok(extendsInfo==null? 0: extendsInfo.get("baseLoad"));
    }

    @PostMapping("configType")
    public BaseResponse configType(HttpServletRequest request, @RequestBody SpaceConfigRequest spaceConfigRequest){
        log.info("config ===> spaceConfigRequest:{}", spaceConfigRequest);
        if(spaceConfigRequest.getType()==null){
            log.error("config type is null,spaceConfigRequest:{}", spaceConfigRequest);
            return BaseResponse.error("系统用电模式不能为空", ResultCode.PARAM_ERROR);
        }
        if(spaceConfigRequest.getId()==null){
            log.error("config spaceInfoId is null,spaceConfigRequest:{}", spaceConfigRequest);
            return BaseResponse.error("系统id不能为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String customerId = JwtUtils.getCustomerId(token);
        SaasSpaceInfo space = spaceService.getSpaceById(spaceConfigRequest.getId());
        if(space==null){
            log.error("config space is null,spaceInfoId:{}", spaceConfigRequest.getId());
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }

        BaseResponse validateSpace = validateSpace(spaceConfigRequest.getId(), token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("config validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }

        List<AssetBasicData> assetBasicDatas = rexolarApiClient.getCustomerAssets(customerId, token);
        AssetBasicData spaceBasicData = assetBasicDatas.stream().filter(assetBasicData -> assetBasicData.getName()
                .equals(space.getName())).findFirst().orElse(null);
        if(spaceBasicData==null){
            log.error("config getCustomerAssetsByName space fail, customerId:{}, spaceName:{}", customerId, space.getName());
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }
        space.setType(spaceConfigRequest.getType());
        return BaseResponse.ok(spaceService.configCtSpace(space));
    }

    @PostMapping("configBaseLoad")
    public BaseResponse configBaseLoad(HttpServletRequest request, @RequestBody SpaceBaseBaseLoadRequest spaceBaseBaseLoadRequest){
        log.info("configBaseLoad ===> spaceConfigRequest:{}", spaceBaseBaseLoadRequest);
        if(spaceBaseBaseLoadRequest.getBaseLoad()==null){
            log.error("configBaseLoad baseLoad is null,spaceBaseBaseLoadRequest:{}", spaceBaseBaseLoadRequest);
            return BaseResponse.error("系统基本负载不能为空", ResultCode.PARAM_ERROR);
        }
        if(spaceBaseBaseLoadRequest.getId()==null){
            log.error("configBaseLoad spaceInfoId is null,spaceConfigRequest:{}", spaceBaseBaseLoadRequest);
            return BaseResponse.error("系统id不能为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String customerId = JwtUtils.getCustomerId(token);
        SaasSpaceInfo space = spaceService.getSpaceById(spaceBaseBaseLoadRequest.getId());
        if(space==null){
            log.error("configBaseLoad space is null,spaceInfoId:{}", spaceBaseBaseLoadRequest.getId());
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }

        String tenantToken = getCustomerSpaceTenantToken(token, space.getId());
        if(StringUtils.isEmpty(tenantToken)){
            log.error("configBaseLoad getCustomerSpaceTenantToken fail, customerId:{}, spaceInfoId:{}", customerId, space.getId());
            return BaseResponse.error("系统不存在", ResultCode.PARAM_ERROR);
        }

        List<AssetBasicData> assetBasicDatas = rexolarApiClient.getCustomerAssets(customerId, tenantToken);
        AssetBasicData spaceBasicData = assetBasicDatas.stream().filter(assetBasicData -> assetBasicData.getName()
                .equals(space.getName())).findFirst().orElse(null);
        if(spaceBasicData==null){
            log.error("configBaseLoad getCustomerAssetsByName space fail, customerId:{}, spaceName:{}", customerId, space.getName());
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }
        JSONObject extendsInfo = JSONObject.parseObject(space.getExtendsInfo());
        if(extendsInfo==null){
            extendsInfo = new JSONObject();
        }
        extendsInfo.put("baseLoad", spaceBaseBaseLoadRequest.getBaseLoad());
        space.setExtendsInfo(extendsInfo.toJSONString());
        return BaseResponse.ok(spaceService.configCtSpace(space));
    }

    @PostMapping("setDefault")
    public BaseResponse setDefault(HttpServletRequest request, @RequestBody SpaceDefaultRequest spaceDefaultRequest){
        log.info("setDefault ===> spaceConfigRequest:{}", spaceDefaultRequest);
        if(spaceDefaultRequest.getSpaceId()==null){
            log.error("setDefault spaceInfoId is null,spaceConfigRequest:{}", spaceDefaultRequest);
            return BaseResponse.error("系统id不能为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        SaasSpaceInfo space = spaceService.getSpaceById(spaceDefaultRequest.getSpaceId());
        if(space==null){
            log.error("setDefault space is null,spaceInfoId:{}", spaceDefaultRequest.getSpaceId());
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }

        BaseResponse validateSpace = validateSpace(spaceDefaultRequest.getSpaceId(), token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("setDefault validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }

        return BaseResponse.ok(spaceService.setDefault(space, token));
    }


    @GetMapping("getCustomerDeviceList")
    public BaseResponse getCustomerDeviceList(HttpServletRequest request, @RequestParam Long id){
        log.info("getCustomerDeviceList ===> spaceInfoId:{}", id);
        if (id == null){
            log.error("getDeviceList spaceInfoId is null,spaceInfoId:{}", id);
            return BaseResponse.error("id不能为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String customerId = JwtUtils.getCustomerId(token);
        SaasSpaceInfo space = spaceService.getSpaceById(id);
        if(space==null){
            log.error("getDeviceList space is null,spaceInfoId:{}", id);
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }
        BaseResponse validateSpace = validateSpace(id, token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("getDeviceList validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }

        String tenantToken = rexolarApiClient.getTenantToken(space.getTenantId());
        if(tenantToken==null){
            log.error("getDeviceList tenantToken is null,space:{}", space);
            return BaseResponse.error("租户不存在", ResultCode.PARAM_ERROR);
        }

        List<AssetBasicData> assetBasicDatas = rexolarApiClient.getCustomerAssets(customerId, tenantToken);
        AssetBasicData spaceBasicData = assetBasicDatas.stream().filter(assetBasicData -> assetBasicData.getName()
                .equals(space.getName())).findFirst().orElse(null);
        if(spaceBasicData==null){
            log.error("getDeviceList getCustomerAssetsByName space fail, customerId:{}, spaceName:{}", customerId, space.getName());
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }

        List<SaasSpaceDeviceRelation> deviceList = spaceService.getCustomerDeviceList(id, JwtUtils.getCustomerId(token));
        if(CollectionUtils.isEmpty(deviceList)){
            log.error("getDeviceList deviceList is null,spaceInfoId:{}", id);
            return BaseResponse.ok(new ArrayList<>());
        }
        Map<String, String> deviceProfiles = rexolarApiClient.getDeviceProfiles(tenantToken);
        if(deviceProfiles==null){
            log.error("getDeviceList deviceProfiles is null,spaceInfoId:{}", id);
        }

        List<SaasSpaceDevicesResponse> relations = new ArrayList<>();
        for (SaasSpaceDeviceRelation saasSpaceDeviceRelation : deviceList){
            String deviceName = saasSpaceDeviceRelation.getDeviceName();
            DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, tenantToken);
            if(deviceBasicData==null){
                log.error("getDeviceList getDeviceByDeviceName error, saasSpaceDeviceRelation.deviceName:{}", saasSpaceDeviceRelation.getDeviceName());
                continue;
            }
            SaasSpaceDevicesResponse response = new SaasSpaceDevicesResponse();
            response.setCategoryId(deviceBasicData.getProfileId());
            response.setCategoryName(deviceProfiles==null? null : deviceProfiles.get(deviceBasicData.getProfileId()));
            BeanUtils.copyProperties(saasSpaceDeviceRelation, response);
            response.setSpaceId(saasSpaceDeviceRelation.getSpaceInfoId());
            response.setSpaceName(space.getName());
            relations.add(response);
        }
        return BaseResponse.ok(relations);
    }

    @PostMapping("bindCustomerDevices")
    public BaseResponse bindCustomerDevices(HttpServletRequest request, @RequestBody SpaceDeviceRequest spaceDeviceRequest){
        log.info("bindCustomerDevices ===> spaceDeviceRequest:{}", spaceDeviceRequest);
        if(CollectionUtils.isEmpty(spaceDeviceRequest.getDeviceRelationInfoList())){
            log.error("bindCustomerDevices deviceRelationInfoList is null,spaceInfoId:{}", spaceDeviceRequest.getDeviceRelationInfoList());
            return BaseResponse.error("设备列表不能为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String customerId = JwtUtils.getCustomerId(token);
        SaasSpaceInfo space = spaceService.getSpaceById(spaceDeviceRequest.getId());
        if(space==null){
            log.error("bindCustomerDevices space is null,spaceInfoId:{}", spaceDeviceRequest.getId());
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }
        BaseResponse validateSpace = validateSpace(spaceDeviceRequest.getId(), token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("bindCustomerDevices validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }

        List<AssetBasicData> assetBasicDatas = rexolarApiClient.getCustomerAssets(customerId, token);
        AssetBasicData spaceBasicData = assetBasicDatas.stream().filter(assetBasicData -> assetBasicData.getName()
                .equals(space.getName())).findFirst().orElse(null);
        if(spaceBasicData==null){
            log.error("bindCustomerDevices getCustomerAssetsByName space fail, customerId:{}, spaceName:{}", customerId, space.getName());
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }

        List<DeviceRelationInfo> devices = spaceDeviceRequest.getDeviceRelationInfoList();
        if(devices!=null && !devices.isEmpty()){
            List<DeviceBasicData> devicesList = rexolarApiClient.getCustomerDevices(customerId, token);
            for(DeviceRelationInfo deviceRelationInfo : devices){
                if(StringUtils.isEmpty(deviceRelationInfo.getDeviceName())){
                    log.error("bindCustomerDevices deviceName is null,deviceRelationInfo:{}", deviceRelationInfo);
                    return BaseResponse.error("设备名称不能为空", ResultCode.PARAM_ERROR);
                }
                if(deviceRelationInfo.getType()==null){
                    log.error("bindCustomerDevices deviceType is null,deviceRelationInfo:{}", deviceRelationInfo);
                    return BaseResponse.error("设备类型不能为空", ResultCode.PARAM_ERROR);
                }
                if(space.getType().intValue() == SpaceTypeEnum.POWER_MONITORING.getCode()){
                    if(deviceRelationInfo.getType()!=1
                            && deviceRelationInfo.getType()!=2
                    ){
                        log.error("bindCustomerDevices POWER_MONITORING deviceType is error,deviceRelationInfo:{}", deviceRelationInfo);
                        return BaseResponse.error("POWER_MONITORING 设备类型不正确", ResultCode.PARAM_ERROR);
                    }
                }else if(space.getType().intValue() == SpaceTypeEnum.SOCKET_MONITORING.getCode()){
                    if(deviceRelationInfo.getType()!=3){
                        log.error("bindCustomerDevices SOCKET_MONITORING deviceType is error,deviceRelationInfo:{}", deviceRelationInfo);
                        return BaseResponse.error("SOCKET_MONITORING 设备类型不正确", ResultCode.PARAM_ERROR);
                    }
                }

                DeviceBasicData customerDevice = devicesList.stream().filter(deviceBasicData -> deviceBasicData.getName()
                        .equals(deviceRelationInfo.getDeviceName())).findFirst().orElse(null);
                if (customerDevice==null){
                    log.error("bindCustomerDevices getCustomerDevicesByName device fail, customerId:{}, deviceName:{}", customerId, deviceRelationInfo.getDeviceName());
                    return BaseResponse.error("设备不属于该用户,"+deviceRelationInfo.getDeviceName(), ResultCode.PARAM_ERROR);
                }
                List<SaasSpaceDeviceRelation> spaces = spaceService.getSpaceByDeviceName(deviceRelationInfo.getDeviceName());
                if(!CollectionUtils.isEmpty(spaces)){
                    for (SaasSpaceDeviceRelation saasSpaceDeviceRelation : spaces){
                        if(!saasSpaceDeviceRelation.getSpaceInfoId().equals(space.getId())){
                            log.error("bindCustomerDevices device is already bind, spaceInfoId:{}", space.getId());
                            return BaseResponse.error("该设备已经绑定其他空间", ResultCode.PARAM_ERROR);
                        }
                    }
                }
            }
        }
        return BaseResponse.ok(spaceService.bindCustomerDevices(space, devices, token));
    }



    @PostMapping("configPrice")
    public BaseResponse configPrice(HttpServletRequest request, @RequestBody SpacePriceRequest spacePriceRequest){
        log.info("configDevices ===> spacePriceRequest:{}", spacePriceRequest);
        if(spacePriceRequest.getSpaceId()==null){
            log.error("configPrice spaceInfoId is null,spacePriceRequest:{}", spacePriceRequest);
            return BaseResponse.error("空间id不能为空", ResultCode.PARAM_ERROR);
        }
        if(spacePriceRequest.getType()==null){
            log.error("configPrice type is null,spacePriceRequest:{}", spacePriceRequest);
            return BaseResponse.error("电价模式不能为空", ResultCode.PARAM_ERROR);
        }
        if(spacePriceRequest.getOutPrice()==null){
            log.error("configPrice outPrice is null,spacePriceRequest:{}", spacePriceRequest);
            return BaseResponse.error("电价输出价格不能为空", ResultCode.PARAM_ERROR);
        }
        if(spacePriceRequest.getImportPrice()==null){
            log.error("configPrice importPrice is null,spacePriceRequest:{}", spacePriceRequest);
            return BaseResponse.error("电价输入价格不能为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        BaseResponse validateSpace = validateSpace(spacePriceRequest.getSpaceId(), token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("configCtSpace validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }
        return BaseResponse.ok(spaceService.configPrice(spacePriceRequest));
    }

    @GetMapping("price")
    public BaseResponse price(HttpServletRequest request, @RequestParam Long spaceId){
        log.info("getSpacePrice ===> spaceInfoId:{}", spaceId);
        if (spaceId == null){
            log.error("getSpacePrice spaceInfoId is null,spaceInfoId:{}", spaceId);
            return BaseResponse.error("spaceId不能为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        BaseResponse validateSpace = validateSpace(spaceId, token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("getSpacePrice validateSpace fail, vaildateSpace:{}", validateSpace);
            return validateSpace;
        }
        SaasSpacePrice saasSpacePrice = spaceService.getSpacePrice(spaceId);
        if(saasSpacePrice==null){
            log.error("getSpacePrice saasSpacePrice is null,spaceInfoId:{}", spaceId);
            return BaseResponse.error("系统价格不存在", ResultCode.PARAM_ERROR);
        }

        SaasSpacePriceResponse saasSpacePriceResponse = new SaasSpacePriceResponse();
        BeanUtils.copyProperties(saasSpacePrice, saasSpacePriceResponse);
        List<SpacePriceDetails> priceDetails = new ArrayList<>();
        if(PriceTypeEnum.Segmented.getCode().equals(saasSpacePrice.getType())){
            List<SaasSpacePriceDetails> spacePriceDetails = spaceService.getSpacePriceDetailsByPriceId(saasSpacePrice.getId());
            for (SaasSpacePriceDetails spacePriceDetail : spacePriceDetails){
                SpacePriceDetails details = new SpacePriceDetails();
                BeanUtils.copyProperties(spacePriceDetail, details);
                priceDetails.add(details);
            }
        }else if(PriceTypeEnum.Fixed.getCode().equals(saasSpacePrice.getType())){
            SpacePriceDetails details = new SpacePriceDetails();
            details.setImportPrice(saasSpacePrice.getImportPrice());
            details.setOutPrice(saasSpacePrice.getOutPrice());
            priceDetails.add(details);
        }
        saasSpacePriceResponse.setPriceDetails(priceDetails);
        return BaseResponse.ok(saasSpacePriceResponse);
    }

    @GetMapping("energy")
    public BaseResponse energy(HttpServletRequest request, @RequestParam Long spaceId){
        log.info("energy ===> spaceInfoId:{}", spaceId);
        String token = request.getHeader("token");
        BaseResponse validateSpace = validateSpace(spaceId, token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("energy validateSpace fail, vaildateSpace:{}", validateSpace);
            return validateSpace;
        }
        SpaceEnergyTotalResponse  spaceEnergyTotalResponse = new SpaceEnergyTotalResponse();
        spaceEnergyTotalResponse.setSpaceId(spaceId);
        List<SpaceEnergyResponse> spaceEnergyResponseList = statisticsService.getAllEnergy(spaceId);
        float gridElectricity = 0f;
        float photovoltaic = 0f;
        float LoadElectricity = 0f;
        for (SpaceEnergyResponse spaceEnergyResponse : spaceEnergyResponseList){
            photovoltaic += spaceEnergyResponse.getPCeiTotal();
            gridElectricity += spaceEnergyResponse.getGCeiTotal();
            LoadElectricity += spaceEnergyResponse.getGCeiTotal() + spaceEnergyResponse.getPCeiTotal() - spaceEnergyResponse.getGCeeTotal();
        }
        spaceEnergyTotalResponse.setPhotovoltaic(photovoltaic);
        spaceEnergyTotalResponse.setGridElectricity(gridElectricity);
        spaceEnergyTotalResponse.setLoadElectricity(LoadElectricity);
        spaceEnergyTotalResponse.setCo2(photovoltaic * 0.4f);
        return BaseResponse.ok(spaceEnergyTotalResponse);
    }

    @GetMapping("power")
    public BaseResponse power(HttpServletRequest request, @RequestParam Long spaceId){
        log.info("power ===> spaceInfoId:{}", spaceId);
        String token = request.getHeader("token");
        BaseResponse validateSpace = validateSpace(spaceId, token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("power validateSpace fail, vaildateSpace:{}", validateSpace);
            return validateSpace;
        }
        return BaseResponse.ok(spaceService.getSpacePower((SaasSpaceInfo) validateSpace.getData()));
    }

    @GetMapping("priceDetails")
    public BaseResponse priceDetails(HttpServletRequest request, @RequestParam Long spaceId){
        log.info("priceDetails ===> spaceInfoId:{}", spaceId);
        String token = request.getHeader("token");
        BaseResponse validateSpace = validateSpace(spaceId, token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("priceDetails validateSpace fail, vaildateSpace:{}", validateSpace);
            return validateSpace;
        }
        return BaseResponse.ok(spaceService.priceDetails(spaceId));
    }
    @DeleteMapping("delete")
    public BaseResponse delete(HttpServletRequest request, @RequestParam Long spaceId){
        log.info("delete ===> spaceInfoId:{}", spaceId);
        String token = request.getHeader("token");
        BaseResponse baseResponse = validateSpace(spaceId, token);
        if(BaseResponse.ok().getCode()!=baseResponse.getCode()){
            log.error("delete validateSpace fail, vaildateSpace:{}", baseResponse);
            return baseResponse;
        }
        String tenantToken = rexolarApiClient.getTenantToken(JwtUtils.getTenantId( token));
        return BaseResponse.ok(spaceService.delete(spaceId, tenantToken));
    }

    @DeleteMapping("deletePriceDetails")
    public BaseResponse deletePriceDetails(HttpServletRequest request, @RequestParam Long priceDetailsId){
        log.info("deletePriceDetails ===> priceDetailsId:{}", priceDetailsId);
        String token = request.getHeader("token");
        SaasSpacePriceDetails saasSpacePriceDetails = spaceService.getSpacePriceDetailsById(priceDetailsId);
        if(saasSpacePriceDetails==null){
            log.error("deletePriceDetails saasSpacePriceDetails is null,priceDetailsId:{}", priceDetailsId);
            return BaseResponse.error("价格详情不存在", ResultCode.PARAM_ERROR);
        }
        SaasSpacePrice saasSpacePrice = spaceService.getSpacePriceById(saasSpacePriceDetails.getSpacePriceId());
        if (saasSpacePrice==null){
            log.error("deletePriceDetails saasSpacePrice is null,priceDetailsId:{}", priceDetailsId);
            return BaseResponse.error("分段价格不存在", ResultCode.PARAM_ERROR);
        }
        SaasSpaceInfo spaceInfo = spaceService.getSpaceById(saasSpacePrice.getSpaceId());
        if(spaceInfo==null){
            log.error("deletePriceDetails spaceInfo is null,priceDetailsId:{}", priceDetailsId);
            return BaseResponse.error("空间不存在", ResultCode.PARAM_ERROR);
        }
        if(!spaceInfo.getCustomerId().equals(JwtUtils.getCustomerId(token))){
            log.error("deletePriceDetails customerId not match, priceDetailsId:{}", priceDetailsId);
            return BaseResponse.error("非法空间", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok(spaceService.deletePriceDetails(priceDetailsId));
    }
    @PostMapping("addPriceDetails")
    public BaseResponse addPriceDetails(HttpServletRequest request, @RequestBody PriceDetailsRequest priceDetailsRequest){
        log.info("addPriceDetails ===> priceDetailsRequest:{}", priceDetailsRequest);
        String token = request.getHeader("token");
        if(priceDetailsRequest.getSpaceId()==null){
            log.error("addPriceDetails spaceId is null,priceDetailsRequest:{}", priceDetailsRequest);
            return BaseResponse.error("空间ID不能为空", ResultCode.PARAM_ERROR);
        }
        if(priceDetailsRequest.getStartDate()==null){
            log.error("addPriceDetails startDate is null,priceDetailsRequest:{}", priceDetailsRequest);
            return BaseResponse.error("开始时间不能为空", ResultCode.PARAM_ERROR);
        }
        if(priceDetailsRequest.getEndDate()==null){
            log.error("addPriceDetails endDate is null,priceDetailsRequest:{}", priceDetailsRequest);
            return BaseResponse.error("结束时间不能为空", ResultCode.PARAM_ERROR);
        }
        if(priceDetailsRequest.getStartTime()==null){
            log.error("addPriceDetails startTime is null,priceDetailsRequest:{}", priceDetailsRequest);
            return BaseResponse.error("开始时间不能为空", ResultCode.PARAM_ERROR);
        }
        if(priceDetailsRequest.getEndTime()==null){
            log.error("addPriceDetails endTime is null,priceDetailsRequest:{}", priceDetailsRequest);
            return BaseResponse.error("结束时间不能为空", ResultCode.PARAM_ERROR);
        }
        if(priceDetailsRequest.getImportPrice()==null){
            log.error("addPriceDetails importPrice is null,priceDetailsRequest:{}", priceDetailsRequest);
            return BaseResponse.error("购买电价不能为空", ResultCode.PARAM_ERROR);
        }

        List<SaasSpacePrice> prices = spaceService.getSpacePriceBySpaceId(priceDetailsRequest.getSpaceId());
        if(CollectionUtils.isEmpty( prices)){
            log.error("addPriceDetails saasSpacePrice is null,spaceId:{}", priceDetailsRequest.getSpaceId());
            return BaseResponse.error("系统价格不存在", ResultCode.PARAM_ERROR);
        }
        SaasSpacePrice saasSpacePrice = prices.get(0);
        if(!saasSpacePrice.getType().equals(PriceTypeEnum.Segmented.getCode())){
            log.error("addPriceDetails saasSpacePrice is not electricity, spaceId:{}, saasSpacePrice:{}", saasSpacePrice.getSpaceId(), saasSpacePrice);
            return BaseResponse.error("系统价格不存在", ResultCode.PARAM_ERROR);
        }
        BaseResponse validateSpace = validateSpace(priceDetailsRequest.getSpaceId(), token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("addPriceDetails validateSpace fail, vaildateSpace:{}", validateSpace);
            return validateSpace;
        }
        List<SpacePriceDetailsResponse> details = spaceService.priceDetails(saasSpacePrice.getId());
        if(details.size() >= 20){
            log.error("addPriceDetails priceDetails is too many, spaceInfoId:{}", saasSpacePrice.getSpaceId());
            return BaseResponse.error("价格详情不能超过20条", ResultCode.PARAM_ERROR);
        }
        for(SpacePriceDetailsResponse spacePriceDetailsResponse : details){
            if (isOverlapping(spacePriceDetailsResponse.getStartDate(), spacePriceDetailsResponse.getEndDate(),
                    priceDetailsRequest.getStartDate(),  priceDetailsRequest.getEndDate())){
                if (isOverlapping(spacePriceDetailsResponse.getStartTime(), spacePriceDetailsResponse.getEndTime(),
                        priceDetailsRequest.getStartTime(), priceDetailsRequest.getEndTime())){
                    log.error("addPriceDetails priceDetailsRequest is overlap, priceDetailsRequest:{}, spacePriceDetailsResponse:{}"
                            , priceDetailsRequest, spacePriceDetailsResponse);
                    return BaseResponse.error("分段电价时间段重叠 ", ResultCode.PARAM_ERROR);
                }
            }
        }
        priceDetailsRequest.setSpacePriceId(saasSpacePrice.getId());
        return BaseResponse.ok(spaceService.addPriceDetails(priceDetailsRequest));
    }
    public static boolean isOverlapping(String startTime1, String endTime1,
                                        String startTime2, String endTime2) {
        // 如果第一个时间段的结束时间在第二个时间段的开始时间之前，或者
        // 第二个时间段的结束时间在第一个时间段的开始时间之前，则它们不冲突
        if (endTime1.compareTo(startTime2) <= 0 || endTime2.compareTo(startTime1) <= 0) {
            return false;
        }
        // 否则，它们冲突
        return true;
    }

    public static void main(String[] args) {
        String startDate1 = "02-01";
        String endDate1 = "02-20";
        String startTime1 = "08:00";
        String endTime1 = "09:00";

        String startDate2 = "01-02";
        String endDate2 = "03-22";
        String startTime2 = "09:01";
        String endTime2 = "10:00";

        SpacePriceDetailsResponse spacePriceDetailsResponse = new SpacePriceDetailsResponse();
        spacePriceDetailsResponse.setStartDate(startDate1);
        spacePriceDetailsResponse.setEndDate(endDate1);
        spacePriceDetailsResponse.setStartTime(startTime1);
        spacePriceDetailsResponse.setEndTime(endTime1);

        PriceDetailsRequest priceDetailsRequest = new PriceDetailsRequest();
        priceDetailsRequest.setStartDate(startDate2);
        priceDetailsRequest.setEndDate(endDate2);
        priceDetailsRequest.setStartTime(startTime2);
        priceDetailsRequest.setEndTime(endTime2);

        if (isOverlapping(spacePriceDetailsResponse.getStartDate(), spacePriceDetailsResponse.getEndDate(),
                priceDetailsRequest.getStartDate(),  spacePriceDetailsResponse.getEndDate())){
            if (isOverlapping(spacePriceDetailsResponse.getStartTime(), spacePriceDetailsResponse.getEndTime(),
                    priceDetailsRequest.getStartTime(), priceDetailsRequest.getEndTime())){
                log.error("addPriceDetails priceDetailsRequest is overlap");
            }
        }
    }
}
